package com.blyat.xsoft.gateway.autoconfigurator;

import com.blyat.xsoft.gateway.ribbon.XSoftLoadBalancerClient;
import com.blyat.xsoft.gateway.ribbon.filter.gateway.IPForbidGatewayFilterFactory;
import com.blyat.xsoft.gateway.ribbon.filter.global.ElapsedFilter;
import com.blyat.xsoft.gateway.ribbon.loadbalancer.rule.LoadBalancerRuleService;
import com.blyat.xsoft.gateway.ribbon.loadbalancer.server.ServerLoader;
import com.blyat.xsoft.gateway.ribbon.router.database.DatabaseRouteDefinitionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.reactive.HiddenHttpMethodFilter;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

/**
 * @Auther: syh
 * @Date: 2020/8/21
 * @Description:
 */
@Configuration
public class GatewayAutoConfiguration {

    @Autowired
    private ServerLoader serverLoader;

    @Autowired
    private LoadBalancerRuleService ruleService;

    /**
     * 负载均衡客户端：载入负载实例
     * 使用代码代替spring cloud中xxxx.ribbon.NFLoadBalancerRuleClassName等相关配置
     *
     * @param factory
     * @return
     */
    @Bean
    public LoadBalancerClient loadBalancerClient(SpringClientFactory factory) {
        XSoftLoadBalancerClient client = new XSoftLoadBalancerClient(factory);
        client.setRuleService(ruleService);
        // serverLoader必须指定
        client.setServerLoader(serverLoader);
        return client;
    }

    @Bean
    public RouteDefinitionRepository routeDefinitionRepository() {
        return new DatabaseRouteDefinitionRepository();
        // return new FileRouteDefinitionRepository();
    }

    /**
     * 全局过滤器
     *
     * @return
     */
    @Bean
    public GlobalFilter elapsedFilter() {
        return new ElapsedFilter();
    }

    /**
     * 局部过滤器，配合routers.json的filter使用
     *
     * @return
     */
    @Bean
    public GatewayFilterFactory ipForbidGatewayFilterFactory() {
        return new IPForbidGatewayFilterFactory();
    }

    /**
     * 修复 Only one connection receive subscriber allowed.的bug
     * 第1种 禁用httpMethodFilter, 新版本默认禁用了。
     * 第2种 spring cloud 版本SR4的bug。将版本修改为Hoxton.SR5
     *
     * @return
     */
    // @Bean
    public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
        return new HiddenHttpMethodFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
                return chain.filter(exchange);
            }
        };

    }
}
